#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>

//int g_val = 100;

//int main()
//{
//    pid_t id = fork();
//    if(id == 0)
//    {
//        int cnt = 5;
//        while(1)
//        {
//            printf("I am a child, pid: %d, ppid: %d, g_val: %d, &g_val: %p\n",getpid(),getppid(),g_val,&g_val);
//            sleep(1);
//            if(cnt)
//            {
//                cnt--;
//            }
//            else
//            {
//                g_val = 200;
//                printf("子进程change g_val: 100->200\n");
//                cnt--;
//            }
//        }
//    }
//    else
//    {
//        while(1)
//        {
//            printf("I am a parent, pid: %d, ppid: %d, g_val: %d, &g_val: %p\n",getpid(),getppid(),g_val,&g_val);
//            sleep(1);
//        }
//    }

//    return 0;
//}

int g_val_1;
int g_val_2 = 100;

int main(int argc, char* argv[], char* env[])
{
    printf("code addr: %p\n", main); //代码区
    const char* str = "hello bit"; //字符串常量
    printf("read only string addr: %p\n", str); //字符常量区
    printf("init global value addr: %p\n", &g_val_2); //已初始化全局变量区
    printf("uninit global value addr: %p\n",&g_val_1); //未初始化全局变量区
    char* mem = (char*)malloc(100); //堆上开辟空间
    char* mem1 = (char*)malloc(100); //堆上开辟空间
    char* mem2 = (char*)malloc(100); //堆上开辟空间
    printf("heap addr: %p\n",mem); //堆区（向上增长）
    printf("heap addr: %p\n",mem1); //堆区
    printf("heap addr: %p\n",mem2); //堆区
    printf("stack addr: %p\n",&str); //栈区（向下增长）
    printf("stack addr: %p\n",&mem); //栈区
    static int a = 0; 
    int b;
    int c;
    printf("a = stack addr: %p\n", &a); //静态数据 static修饰的变量在编译时已被编译到全局数据区
    printf("b = stack addr: %p\n", &b); //栈区
    printf("c = stack addr: %p\n", &c); //栈区
    int i = 0;
    for(; argv[i]; i++)     //命令行参数
    {
        printf("argv[%d]: %p\n", i, argv[i]);
    }
    for(i = 0; env[i]; i++)     //环境变量
    {
        printf("env[%d]: %p\n", i, env[i] );
    }

    return 0;
}